/* Copyright 2010 OddRain
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.oddrain.wifieditor.pro;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

public class WifiConfigList extends Activity implements
	OnSharedPreferenceChangeListener {

    protected static final int SHOW_PREFERENCES = 0;
    private WifiManager wifi;
    private ListView wifiConfigListView;
    private List<WifiConfiguration> wifiConfigList;
    private WifiConfiguration selectedConfig;
    private WifiConfigurationAdapter aa;
    private boolean editingPrefs = false;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	// Setup WiFi
	wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
	wifiConfigListView = (ListView) findViewById(R.id.wifiConfigList);

	wifiConfigListView.setOnItemClickListener(new OnItemClickListener() {
	    public void onItemClick(AdapterView<?> _av, View _v, int _index,
		    long arg3) {
		selectedConfig = wifiConfigList.get(_index);

		// Populate Preferences
		Context context = getApplicationContext();
		SharedPreferences prefs = PreferenceManager
			.getDefaultSharedPreferences(context);
		prefs
			.registerOnSharedPreferenceChangeListener(WifiConfigList.this);
		SharedPreferences.Editor editor = prefs.edit();
		editor.clear();

		if (selectedConfig.SSID != null
			&& selectedConfig.SSID.length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_SSID,
			    selectedConfig.SSID.substring(1,
				    selectedConfig.SSID.length() - 1));
		}
		editor.putBoolean(WifiConfigSettings.PREF_HIDDEN_SSID,
			selectedConfig.hiddenSSID);

		editor.putBoolean(WifiConfigSettings.PREF_KEY_NONE,
			selectedConfig.allowedKeyManagement
				.get(WifiConfiguration.KeyMgmt.NONE));
		editor.putBoolean(WifiConfigSettings.PREF_KEY_PSK,
			selectedConfig.allowedKeyManagement
				.get(WifiConfiguration.KeyMgmt.WPA_PSK));
		editor.putBoolean(WifiConfigSettings.PREF_KEY_EAP,
			selectedConfig.allowedKeyManagement
				.get(WifiConfiguration.KeyMgmt.WPA_EAP));
		editor.putBoolean(WifiConfigSettings.PREF_KEY_IEEE,
			selectedConfig.allowedKeyManagement
				.get(WifiConfiguration.KeyMgmt.IEEE8021X));

		editor.putBoolean(WifiConfigSettings.PREF_AUTH_OPEN,
			selectedConfig.allowedAuthAlgorithms
				.get(WifiConfiguration.AuthAlgorithm.OPEN));
		editor.putBoolean(WifiConfigSettings.PREF_AUTH_LEAP,
			selectedConfig.allowedAuthAlgorithms
				.get(WifiConfiguration.AuthAlgorithm.LEAP));
		editor.putBoolean(WifiConfigSettings.PREF_AUTH_SHARED,
			selectedConfig.allowedAuthAlgorithms
				.get(WifiConfiguration.AuthAlgorithm.SHARED));

		editor.putBoolean(WifiConfigSettings.PREF_SEC_WPA,
			selectedConfig.allowedProtocols
				.get(WifiConfiguration.Protocol.WPA));
		editor.putBoolean(WifiConfigSettings.PREF_SEC_RSN,
			selectedConfig.allowedProtocols
				.get(WifiConfiguration.Protocol.RSN));

		editor.putBoolean(WifiConfigSettings.PREF_PAIR_NONE,
			selectedConfig.allowedPairwiseCiphers
				.get(WifiConfiguration.PairwiseCipher.NONE));
		editor.putBoolean(WifiConfigSettings.PREF_PAIR_CCMP,
			selectedConfig.allowedPairwiseCiphers
				.get(WifiConfiguration.PairwiseCipher.CCMP));
		editor.putBoolean(WifiConfigSettings.PREF_PAIR_TKIP,
			selectedConfig.allowedPairwiseCiphers
				.get(WifiConfiguration.PairwiseCipher.TKIP));

		editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP40,
			selectedConfig.allowedGroupCiphers
				.get(WifiConfiguration.GroupCipher.WEP40));
		editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP104,
			selectedConfig.allowedGroupCiphers
				.get(WifiConfiguration.GroupCipher.WEP104));
		editor.putBoolean(WifiConfigSettings.PREF_GRP_TKIP,
			selectedConfig.allowedGroupCiphers
				.get(WifiConfiguration.GroupCipher.TKIP));
		editor.putBoolean(WifiConfigSettings.PREF_GRP_CCMP,
			selectedConfig.allowedGroupCiphers
				.get(WifiConfiguration.GroupCipher.CCMP));

		if (selectedConfig.wepKeys[0] != null
			&& selectedConfig.wepKeys[0].length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY0,
			    selectedConfig.wepKeys[0].substring(1,
				    selectedConfig.wepKeys[0].length() - 1));
		}

		if (selectedConfig.wepKeys[1] != null
			&& selectedConfig.wepKeys[1].length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY1,
			    selectedConfig.wepKeys[1].substring(1,
				    selectedConfig.wepKeys[1].length() - 1));
		}

		if (selectedConfig.wepKeys[2] != null
			&& selectedConfig.wepKeys[2].length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY2,
			    selectedConfig.wepKeys[2].substring(1,
				    selectedConfig.wepKeys[2].length() - 1));
		}

		if (selectedConfig.wepKeys[3] != null
			&& selectedConfig.wepKeys[3].length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY3,
			    selectedConfig.wepKeys[3].substring(1,
				    selectedConfig.wepKeys[3].length() - 1));
		}

		if (selectedConfig.preSharedKey != null
			&& selectedConfig.preSharedKey.length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_WPA_KEY,
			    selectedConfig.preSharedKey.substring(1,
				    selectedConfig.preSharedKey.length() - 1));
		}

		if (selectedConfig.eap.value() != null) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_EAP,
			    selectedConfig.eap.value());
		}

		if (selectedConfig.phase2.value() != null) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_PHASE2,
			    selectedConfig.phase2.value());
		}

		if (selectedConfig.identity.value() != null
			&& selectedConfig.identity.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_IDENT,
			    selectedConfig.identity.value().substring(1,
				    selectedConfig.identity.value().length() - 1));
		}

		if (selectedConfig.anonymous_identity.value() != null
			&& selectedConfig.anonymous_identity.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_ANON_IDENT,
			    selectedConfig.anonymous_identity.value()
				    .substring(1,
					    selectedConfig.anonymous_identity.value()
						    .length() - 1));
		}

		if (selectedConfig.password.value() != null
			&& selectedConfig.password.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_PASS,
			    selectedConfig.password.value().substring(1,
				    selectedConfig.password.value().length() - 1));
		}

		if (selectedConfig.client_cert.value() != null
			&& selectedConfig.client_cert.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT,
			    selectedConfig.client_cert.value().substring(1,
				    selectedConfig.client_cert.value().length() - 1));
		}

		if (selectedConfig.ca_cert.value() != null
			&& selectedConfig.ca_cert.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_CA_CERT,
			    selectedConfig.ca_cert.value().substring(1,
				    selectedConfig.ca_cert.value().length() - 1));
		}

		if (selectedConfig.private_key.value() != null
			&& selectedConfig.private_key.value().length() >= 2) {
		    editor.putString(WifiConfigSettings.PREF_ENTR_PRIV_KEY,
			    selectedConfig.private_key.value().substring(1,
				    selectedConfig.private_key.value().length() - 1));
		}

		editor.commit();
		editingPrefs = true;

		// Display Preferences
		Intent i = new Intent(context, WifiConfigSettings.class);
		i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
		startActivityForResult(i, SHOW_PREFERENCES);

	    }
	});

	wifiConfigList = new ArrayList<WifiConfiguration>();
	int resID = R.layout.wificonfiguration_item;
	aa = new WifiConfigurationAdapter(this, resID, wifiConfigList);
	wifiConfigListView.setAdapter(aa);

	Context context = getApplicationContext();
	context.registerReceiver(new BroadcastReceiver() {
	    @Override
	    public void onReceive(Context context, Intent intent) {
		loadWifiConfigs();
		System.out.println("Recieved wifi state changed action:"
			+ intent);
	    }
	}, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));

	checkWifiState();
    }

    private void loadWifiConfigs() {
	wifiConfigList.clear();
	List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
	for (WifiConfiguration config : configs) {
	    wifiConfigList.add(config);
	}
	aa.notifyDataSetChanged();
    }

    private void checkWifiState() {
	boolean enabled = wifi.isWifiEnabled();
	if (!enabled) {
	    Builder builder = new AlertDialog.Builder(this);
	    builder.setTitle(getString(R.string.app_name));
	    builder.setIcon(android.R.drawable.ic_dialog_alert);
	    builder.setMessage(getString(R.string.WIFI_ENABLE_MSG));
	    builder.setPositiveButton(getString(R.string.YES),
		    new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			    wifi.setWifiEnabled(true);
			}
		    });
	    builder.setNegativeButton(getString(R.string.NO), null);
	    builder.show();
	} else {
	    loadWifiConfigs();
	}
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);
	checkWifiState();
	editingPrefs = false;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
	    String key) {
	if (editingPrefs) {
	    // Save
	    saveWiFiConfig();
	}
    }

    private void saveWiFiConfig() {
	// Save Wifi Config from Preferences
	Context context = getApplicationContext();
	SharedPreferences prefs = PreferenceManager
		.getDefaultSharedPreferences(context);

	if (prefs.getString(WifiConfigSettings.PREF_SSID, null) != null) {
	    selectedConfig.SSID = "\""
		    + prefs.getString(WifiConfigSettings.PREF_SSID, "") + "\"";
	}

	if (prefs.getBoolean(WifiConfigSettings.PREF_HIDDEN_SSID, false)) {
	    selectedConfig.hiddenSSID = true;
	}

	selectedConfig.allowedKeyManagement.clear();
	if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_IEEE, false)) {
	    selectedConfig.allowedKeyManagement
		    .set(WifiConfiguration.KeyMgmt.IEEE8021X);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_PSK, false)) {
	    selectedConfig.allowedKeyManagement
		    .set(WifiConfiguration.KeyMgmt.WPA_PSK);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_EAP, false)) {
	    selectedConfig.allowedKeyManagement
		    .set(WifiConfiguration.KeyMgmt.WPA_EAP);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_NONE, false)) {
	    selectedConfig.allowedKeyManagement
		    .set(WifiConfiguration.KeyMgmt.NONE);
	}

	// GroupCiphers
	selectedConfig.allowedGroupCiphers.clear();
	if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP40, false)) {
	    selectedConfig.allowedGroupCiphers
		    .set(WifiConfiguration.GroupCipher.WEP40);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP104, false)) {
	    selectedConfig.allowedGroupCiphers
		    .set(WifiConfiguration.GroupCipher.WEP104);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_CCMP, false)) {
	    selectedConfig.allowedGroupCiphers
		    .set(WifiConfiguration.GroupCipher.CCMP);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_TKIP, false)) {
	    selectedConfig.allowedGroupCiphers
		    .set(WifiConfiguration.GroupCipher.TKIP);
	}

	// PairwiseCiphers
	selectedConfig.allowedPairwiseCiphers.clear();
	if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_TKIP, false)) {
	    selectedConfig.allowedPairwiseCiphers
		    .set(WifiConfiguration.PairwiseCipher.TKIP);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_CCMP, false)) {
	    selectedConfig.allowedPairwiseCiphers
		    .set(WifiConfiguration.PairwiseCipher.CCMP);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_NONE, false)) {
	    selectedConfig.allowedPairwiseCiphers
		    .set(WifiConfiguration.PairwiseCipher.NONE);
	}

	// Authentication Algorithms
	selectedConfig.allowedAuthAlgorithms.clear();
	if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_OPEN, false)) {
	    selectedConfig.allowedAuthAlgorithms
		    .set(WifiConfiguration.AuthAlgorithm.OPEN);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_SHARED, false)) {
	    selectedConfig.allowedAuthAlgorithms
		    .set(WifiConfiguration.AuthAlgorithm.SHARED);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_LEAP, false)) {
	    selectedConfig.allowedAuthAlgorithms
		    .set(WifiConfiguration.AuthAlgorithm.LEAP);
	}

	// Protocols
	selectedConfig.allowedProtocols.clear();
	if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_RSN, false)) {
	    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
	}
	if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_WPA, false)) {
	    selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
	}

	// WEP Keys
	if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, null) != null) {
	    selectedConfig.wepKeys[0] = "\""
		    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, "")
		    + "\"";
	}
	if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, null) != null) {
	    selectedConfig.wepKeys[1] = "\""
		    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, "")
		    + "\"";
	}
	if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, null) != null) {
	    selectedConfig.wepKeys[2] = "\""
		    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, "")
		    + "\"";
	}
	if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, null) != null) {
	    selectedConfig.wepKeys[3] = "\""
		    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, "")
		    + "\"";
	}

	if (prefs.getString(WifiConfigSettings.PREF_WPA_KEY, null) != null) {
	    selectedConfig.preSharedKey = "\""
		    + prefs.getString(WifiConfigSettings.PREF_WPA_KEY, "")
		    + "\"";
	}

	// Enterprise Settings
	if (prefs.getString(WifiConfigSettings.PREF_ENTR_EAP, null) != null) {
	    selectedConfig.eap.setValue(prefs.getString(
		    WifiConfigSettings.PREF_ENTR_EAP, null));
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_PHASE2, null) != null) {
	    selectedConfig.phase2.setValue(prefs.getString(
		    WifiConfigSettings.PREF_ENTR_PHASE2, null));
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_IDENT, null) != null) {
	    selectedConfig.identity.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_IDENT, "")
		    + "\"");
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_ANON_IDENT, null) != null) {
	    selectedConfig.anonymous_identity.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_ANON_IDENT,
			    "") + "\"");
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_PASS, null) != null) {
	    selectedConfig.password.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_PASS, "")
		    + "\"");
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT, null) != null) {
	    selectedConfig.client_cert.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT,
			    "") + "\"");
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_CA_CERT, null) != null) {
	    selectedConfig.ca_cert.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_CA_CERT, "")
		    + "\"");
	}

	if (prefs.getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY, null) != null) {
	    selectedConfig.private_key.setValue("\""
		    + prefs.getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY, "")
		    + "\"");
	}

	wifi.updateNetwork(selectedConfig);
	wifi.enableNetwork(selectedConfig.networkId, false);
	wifi.saveConfiguration();
    }
}